if (do_name() != 'Home') : ?>
Mark Meyer | Parametric surfaces | rotating sphere
endif ?>size(550, 550) background(0) nofill() stroke(0.6, 0.6, 0.7, 0.35) strokewidth(0.5) translate(WIDTH/2, HEIGHT/2) # n defines how many vertices we find: the number will be n^2. # Large values of n can take a while to render! n = 27 # Define parametric equations for each axis. # Although we define an z coordinate, # it is only used in transformations and shading; # it is not used in the drawing # (although it could be if you wanted to add perspective). r = 240 def x(u, v): return r * sin(u) * cos(v) def y(u, v): return r * sin(u) * sin(v) def z(u, v): return r * cos(u) def fit_to_domain(u, v): u = 1.0 * u / n * pi v = 1.0 * v / n * pi*2 return u, v from Numeric import * def matrix(u, v, index): u, v = fit_to_domain(u, v) return where(index==0, x(u, v), where(index==1, y(u,v), where(index==2, z(u,v), 1) ) ) def rotate_matrix(matrix, x, y, z): rot_x = array( ([1, 0, 0], [0, cos(x), -sin(x)], [0, sin(x), cos(x)] ), Float ) rot_y = array( ([cos(y), 0, sin(y)], [0, 1, 0], [-sin(y), 0, cos(y)] ), Float ) rot_z = array( ([cos(z), -sin(z), 0], [sin(z), cos(z), 0], [0, 0, 1] ), Float ) matrix = matrixmultiply(matrix, rot_x) matrix = matrixmultiply(matrix, rot_y) matrix = matrixmultiply(matrix, rot_z) return matrix def project(rows): """ Go through the array and draw rectangles. There is probably a more efficent way to do this. """ for i in range(len(rows)-1): for j in range(len(rows[i])-1): beginpath( rows[i][j][0], rows[i][j][1] ) lineto( rows[i+1][j][0], rows[i+1][j][1] ) lineto( rows[i+1][j+1][0], rows[i+1][j+1][1] ) lineto( rows[i][j+1][0], rows[i][j+1][1] ) endpath() # Silders to control the rotation. var("rot_x", NUMBER, 0.0, -pi, pi) var("rot_y", NUMBER, 0.5, -pi, pi) var("rot_z", NUMBER, 0.5, -pi, pi) sphere = fromfunction(matrix, (n+1, n+1, 3)) sphere = rotate_matrix(sphere, rot_x, rot_y, rot_z) project(sphere)include("util/comment.php"); ?>